package com.etnet.streamserver.view.client;

import com.etnet.streamserver.view.client.request.NssRequest;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ClientManager {
    private Logger log = LoggerFactory.getLogger(super.getClass());
    private ExecutorService executorService = Executors.newCachedThreadPool();
    private static ClientManager clientManager = new ClientManager();

    private LinkedBlockingQueue<NssRequest> dequeue = new LinkedBlockingQueue<NssRequest>();
    private ConcurrentHashMap<String, ResultData> data = new ConcurrentHashMap<String, ResultData>();

    boolean isShutdown = false;

    NssClient client = null;
    private String ip;
    private String port;
    TakeMessageHandler handler = new TakeMessageHandler();

    private ClientManager() {
    }

    public boolean putMessage(NssRequest msg) {
        if (!this.isShutdown) {
            try {
                this.dequeue.put(msg);
            } catch (Exception e) {
                this.log.error("put msg error! [" + msg.toString() + "]", e);
            }
        } else {
            this.dequeue.clear();
        }
        return !this.isShutdown;
    }

    public void putResult(String key, ResultData value) {
        data.put(key, value);
    }

    public ResultData getMessageResult(String key) {
        return data.remove(key);
    }

    public void setServerIP(String ips) {
        this.ip = ips;
    }

    public void setServerPort(String ports) {
        this.port = ports;
    }

    public static ClientManager getInstance() {
        return clientManager;
    }

    private void init() {
        this.client = new NssClient(this.ip, this.port, this);
        this.executorService.execute(this.client);
        this.handler.start();
    }

    public void start() {
        init();
    }

    public void close() {
        this.isShutdown = true;
        this.executorService.shutdown();
    }

    class TakeMessageHandler extends Thread {
        public TakeMessageHandler() {
        }

        public void run() {
            while (!ClientManager.this.isShutdown)
                try {
                    NssRequest msg = (NssRequest) ClientManager.this.dequeue.take();
                    if ((ClientManager.this.client != null) && (!ClientManager.this.client.isConnected)) {
                        // ClientManager.this.close();
                        continue;
                    }
                    String msgStr = NssSenderManager.sendMsgStr(msg.getReqID(), msg.getReqActionType(), msg.getData());
                    ClientManager.this.log.info("send Message:[" + msgStr + "]");

                    ClientManager.this.client.sendMessage(msgStr);
                } catch (Exception e) {
                    ClientManager.this.log.error("send msg error!", e);
                }
        }
    }
}